from core.models.user import Customer, Seller, Admin, User
from core.services.data_manager import DataManager
from core.utils.logger import info, warning, error, debug
from core.utils.validators import validate_user
import json
import os

class AuthService:
    def __init__(self):
        self.data_manager = DataManager()
        self.current_user = None
        # Try to auto-login remembered user
        try:
            self._load_remembered()
        except Exception:
            pass
    
    def register(self, username, email, password, role="customer", **kwargs):
        info(f"User registration attempt: {username} ({email}) - role: {role}")
        
        # 验证用户数据
        user_data = {
            'username': username,
            'email': email,
            'password': password,
            'role': role
        }
        
        is_valid, errors = validate_user(user_data)
        if not is_valid:
            error_msg = "; ".join(errors)
            warning(f"User data validation failed: {username} - {error_msg}")
            raise ValueError(error_msg)
        
        users = self.data_manager.load_users()
        
        for user_data in users:
            if user_data['username'] == username:
                raise ValueError("Username already exists")
            if user_data['email'] == email:
                raise ValueError("Email already registered")
        
        user_id = f"user_{len(users) + 1:06d}"
        password_hash = User._hash_password(password)
        
        # 处理安全问题（可选）
        security_question = kwargs.get('security_question')
        security_answer = kwargs.get('security_answer')
        security_answer_hash = None
        if security_question and security_answer:
            security_answer_hash = User.hash_security_answer(security_answer)
        
        if role == "customer":
            user = Customer(user_id, username, email, password_hash,
                          security_question=security_question,
                          security_answer_hash=security_answer_hash)
        elif role == "seller":
            store_name = kwargs.get('store_name', f"{username}'s Store")
            user = Seller(user_id, username, email, password_hash, store_name,
                        security_question=security_question,
                        security_answer_hash=security_answer_hash)
        elif role == "admin":
            user = Admin(user_id, username, email, password_hash,
                       security_question=security_question,
                       security_answer_hash=security_answer_hash)
        else:
            raise ValueError("Unsupported user role")
        
        users.append(user.to_dict())
        self.data_manager.save_users(users)
        info(f"User registration successful: {username} (ID: {user.user_id})")
        return user
    
    def login(self, username, password, remember=False):
        info(f"User login attempt: {username}")
        users = self.data_manager.load_users()
        
        for user_data in users:
            if user_data['username'] == username:
                temp_user = self._create_user_from_data(user_data)
                if temp_user.verify_password(password):
                    self.current_user = temp_user
                    
                    # 强制设置为用户模式（如果用户有customer角色）
                    # 每次登录时都确保从用户模式开始
                    if temp_user.has_role('customer'):
                        temp_user.current_role = 'customer'
                        self._update_user_role(temp_user.user_id, 'customer')
                        info(f"User {username} set to customer mode after login")
                    # 如果用户没有customer角色但有其他角色，使用第一个角色
                    elif temp_user.get_roles():
                        temp_user.current_role = temp_user.get_roles()[0]
                        self._update_user_role(temp_user.user_id, temp_user.current_role)
                    
                    info(f"User login successful: {username} (ID: {temp_user.user_id})")
                    # persist remember-me if requested
                    if remember:
                        try:
                            self._save_remembered(temp_user.user_id)
                            debug(f"Remember login saved: {username}")
                        except Exception as e:
                            warning(f"Failed to save remember login: {e}")
                    else:
                        try:
                            self._clear_remembered()
                        except Exception:
                            pass
                    return self.current_user
        
        warning(f"User login failed: {username} - incorrect username or password")
        raise ValueError("Incorrect username or password")
    
    def logout(self):
        if self.current_user:
            info(f"User logged out: {self.current_user.username}")
        self.current_user = None
        try:
            self._clear_remembered()
        except Exception as e:
            warning(f"Failed to clear remember login: {e}")
    
    def _create_user_from_data(self, user_data):
        """从数据创建用户对象，支持多角色"""
        role = user_data.get('role', 'customer')
        roles = user_data.get('roles', [role])  # 兼容旧数据
        
        if role == "customer":
            user = Customer(
                user_data['user_id'],
                user_data['username'],
                user_data['email'],
                user_data['password_hash'],
                shipping_address=user_data.get('shipping_address'),
                avatar_path=user_data.get('avatar_path'),
                security_question=user_data.get('security_question'),
                security_answer_hash=user_data.get('security_answer_hash'),
                roles=roles
            )
        elif role == "seller":
            user = Seller(
                user_data['user_id'],
                user_data['username'],
                user_data['email'],
                user_data['password_hash'],
                user_data.get('store_name', ''),
                avatar_path=user_data.get('avatar_path'),
                security_question=user_data.get('security_question'),
                security_answer_hash=user_data.get('security_answer_hash'),
                roles=roles
            )
        elif role == "admin":
            user = Admin(
                user_data['user_id'],
                user_data['username'],
                user_data['email'],
                user_data['password_hash'],
                avatar_path=user_data.get('avatar_path'),
                security_question=user_data.get('security_question'),
                security_answer_hash=user_data.get('security_answer_hash'),
                roles=roles
            )
        
        # 恢复多角色信息
        user.roles = roles
        # 如果有customer角色，默认使用customer
        if 'customer' in roles:
            user.current_role = 'customer'
        else:
            user.current_role = role
        
        return user

    # --- remember-me persistence helpers (store a small file in data/) ---
    def _remember_file(self):
        return self.data_manager._get_file_path('remember.json')

    def _save_remembered(self, user_id):
        path = self._remember_file()
        with open(path, 'w', encoding='utf-8') as f:
            json.dump({'user_id': user_id}, f)

    def _load_remembered(self):
        path = self._remember_file()
        if not os.path.exists(path):
            return
        try:
            with open(path, 'r', encoding='utf-8') as f:
                data = json.load(f) or {}
            uid = data.get('user_id')
            if not uid:
                return
            # find user
            users = self.data_manager.load_users()
            for u in users:
                if u.get('user_id') == uid:
                    self.current_user = self._create_user_from_data(u)
                    return
        except Exception:
            return

    def _clear_remembered(self):
        path = self._remember_file()
        try:
            if os.path.exists(path):
                os.remove(path)
        except Exception:
            pass
    
    def is_logged_in(self):
        return self.current_user is not None

    def update_user(self, user_id, **updates):
        """Update user fields (username, email, store_name). Returns updated user instance.

        Raises ValueError on validation errors (duplicate username/email).
        """
        users = self.data_manager.load_users()
        found = False

        # Validate uniqueness if username/email changed
        new_username = updates.get('username')
        new_email = updates.get('email')

        for u in users:
            if u['user_id'] == user_id:
                found = True
                target = u
                continue
            if new_username and u.get('username') == new_username:
                raise ValueError('Username already exists')
            if new_email and u.get('email') == new_email:
                raise ValueError('Email already registered')

        if not found:
            raise ValueError('User does not exist')

        # Apply updates (allow avatar_path as well)
        allowed_keys = ['username', 'email', 'store_name', 'avatar_path']
        for k, v in updates.items():
            if k in allowed_keys:
                target[k] = v

        # Save back
        self.data_manager.save_users(users)

        # If current user is this user, refresh current_user
        if self.current_user and self.current_user.user_id == user_id:
            self.current_user = self._create_user_from_data(target)

        return self._create_user_from_data(target)

    def change_password(self, user_id, old_password, new_password):
        """Change user's password after verifying the old password."""
        users = self.data_manager.load_users()
        target = None

        for u in users:
            if u['user_id'] == user_id:
                target = u
                break

        if not target:
            raise ValueError('User does not exist')

        # 验证新密码强度
        is_valid, error_msg = User.validate_password_strength(new_password)
        if not is_valid:
            raise ValueError(error_msg)

        # 创建临时用户对象来验证旧密码
        temp_user = self._create_user_from_data(target)
        if not temp_user.verify_password(old_password):
            raise ValueError('Current password is incorrect')

        # Update hash and save
        target['password_hash'] = User._hash_password(new_password)
        self.data_manager.save_users(users)

        # If current user is this user, refresh
        if self.current_user and self.current_user.user_id == user_id:
            self.current_user = self._create_user_from_data(target)

        return True
    
    def get_user_by_username(self, username):
        """根据用户名获取用户对象"""
        users = self.data_manager.load_users()
        for user_data in users:
            if user_data['username'] == username:
                return self._create_user_from_data(user_data)
        return None
    
    def reset_password(self, username, new_password):
        """通过安全问题验证后重置密码"""
        users = self.data_manager.load_users()
        target = None
        
        for u in users:
            if u['username'] == username:
                target = u
                break
        
        if not target:
            raise ValueError('User does not exist')
        
        # 验证新密码强度
        is_valid, error_msg = User.validate_password_strength(new_password)
        if not is_valid:
            raise ValueError(error_msg)
        
        # 更新密码哈希
        target['password_hash'] = User._hash_password(new_password)
        self.data_manager.save_users(users)
        
        info(f"Password reset successful: {username}")
        return True
    
    def switch_user_role(self, role):
        """切换当前用户角色"""
        if not self.current_user:
            return False
        
        if self.current_user.switch_role(role):
            # 更新数据文件中的角色信息
            self._update_user_role(self.current_user.user_id, role)
            info(f"User {self.current_user.username} switched role to: {role}")
            return True
        
        warning(f"User {self.current_user.username} cannot switch to role: {role}")
        return False
    
    def _update_user_role(self, user_id, new_role):
        """更新用户数据文件中的当前角色"""
        users = self.data_manager.load_users()
        for user_data in users:
            if user_data['user_id'] == user_id:
                user_data['role'] = new_role
                break
        self.data_manager.save_users(users)